package uk.org.mygrid.eobesity.csvserver.routes;

import java.io.File;
import java.io.IOException;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.Logger;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Parameter;
import org.restlet.data.Status;
import org.restlet.ext.xml.DomRepresentation;
import org.restlet.representation.FileRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Create a Zip file with CSV data for each of the datasets and variables
 * requested. The request is in the style of: <code>
 * <request>
 * <Datasets>
 * <Dataset name="HSE2002">
 * <Variables>
 * <Variable>age</Variable><Variable>year</Variable><Variable>dobmonth</Variable>
 * </Variables>
 * </Dataset>
 * <Dataset name="HSE2003">
 * <Variables>
 * <Variable>height</Variable>
 * </Variables>
 * </Dataset>
 * <Dataset year="HSE2006">
 * <Variables>
 * <Variable>bmi</Variable>
 * </Variables>
 * </Dataset>
 * </Datasets>
 * </request>
 * </code>
 * 
 * @author Ian Dunlop
 * 
 */
public class FetchZipFile extends ServerResource {

    /** The UUID representing the job being run */
    private String jobID;
    private Configuration config;
    private static Logger logger = Logger.getLogger(FetchZipFile.class);

    @Get
    public Representation downloadZipFile() {
        logger.info("download zip");
        Form form = getRequest().getResourceRef().getQueryAsForm();
        Parameter first = form.getFirst("type");
        String download_type;
        if (first == null) {
        	download_type="CSV";
        } else {
        	download_type = (String) first.getValue();        	
        }

        jobID = (String) getRequest().getAttributes().get("jobid");
        try {
            setConfig(new PropertiesConfiguration("csv.properties"));
        } catch (ConfigurationException e1) {
            logger.error("Could not create property file ", e1);
        }
        if (DownloadFile.getFailedJobs().contains(jobID)) {
            DomRepresentation representation;
            try {
                representation = new DomRepresentation(MediaType.TEXT_XML);
                Document d = representation.getDocument();
                Element jobIDElement = d.createElement("status");
                jobIDElement.appendChild(d.createTextNode("Failed"));
                d.appendChild(jobIDElement);
                d.normalizeDocument();
                getResponse().setEntity(representation);
                getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
                return representation;
            } catch (IOException e) {
                logger.warn("Problem returning status for job " + jobID);
                getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
            }
        } else {
            logger.info("Comp jobs " + BaseResource.getCompletedJobList());
            logger.info("Job " + jobID + " complete, returning zip file");
            // return the completed file

            String fileDirectory = getConfig().getString("DownloadFile.31");
            if (download_type.equalsIgnoreCase("CSV")) {
                Boolean completedCSVJob = BaseResource.getCompletedJobList().get(jobID);
                if (completedCSVJob == null) {
                    logger.warn("No such job " + jobID);
                    getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
                } else if (completedCSVJob) {
                    File file = new File(fileDirectory + jobID + ".zip");
                    FileRepresentation representation = new FileRepresentation(
                            file, MediaType.APPLICATION_ZIP, 12345);
                    getResponse().setEntity(representation);
                    getResponse().setStatus(Status.SUCCESS_OK);
                    return representation;
                } else {
                    // return an xml doc with '<status>false</status>'
                    DomRepresentation representation;
                    try {
                        representation = new DomRepresentation(MediaType.TEXT_XML);
                        Document d = representation.getDocument();
                        Element jobIDElement = d.createElement("status");
                        // String progress =
                        // DownloadFile.getNumberProcessed().get(jobID);
                        jobIDElement.appendChild(d.createTextNode("Still processing"));
                        d.appendChild(jobIDElement);
                        d.normalizeDocument();
                        getResponse().setEntity(representation);
                        getResponse().setStatus(Status.SUCCESS_OK);
                        return representation;
                    } catch (IOException e) {
                        logger.warn("Problem returning status for job " + jobID);
                        getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
                    }
                }

            } else if (download_type.equalsIgnoreCase("SPSS")) {
                Boolean spssJob = BaseResource.getSPSSJobList().get(jobID);
                if (spssJob == null) {
                    logger.warn("No such job " + jobID);
                    getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
                } else if (spssJob) {
                    File file = new File(fileDirectory + jobID + "_spss.zip");
                    FileRepresentation representation = new FileRepresentation(
                            file, MediaType.APPLICATION_ZIP, 12345);
                    getResponse().setEntity(representation);
                    getResponse().setStatus(Status.SUCCESS_OK);
                    return representation;
                } else {
                    // return an xml doc with '<status>false</status>'
                    DomRepresentation representation;
                    try {
                        representation = new DomRepresentation(MediaType.TEXT_XML);
                        Document d = representation.getDocument();
                        Element jobIDElement = d.createElement("status");
                        // String progress =
                        // DownloadFile.getNumberProcessed().get(jobID);
                        jobIDElement.appendChild(d.createTextNode("Still processing"));
                        d.appendChild(jobIDElement);
                        d.normalizeDocument();
                        getResponse().setEntity(representation);
                        getResponse().setStatus(Status.SUCCESS_OK);
                        return representation;
                    } catch (IOException e) {
                        logger.warn("Problem returning status for job " + jobID);
                        getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
                    }
                }
            } else if (download_type.equalsIgnoreCase("Stata")) {
                Boolean stataJob = BaseResource.getStataJobList().get(jobID);
                if (stataJob == null) {
                    logger.warn("No such job " + jobID);
                    getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
                } else if (stataJob) {
                    File file = new File(fileDirectory + jobID + "_stata.zip");
                    FileRepresentation representation = new FileRepresentation(
                            file, MediaType.APPLICATION_ZIP, 12345);
                    getResponse().setEntity(representation);
                    getResponse().setStatus(Status.SUCCESS_OK);
                    return representation;
                } else {
                    // return an xml doc with '<status>false</status>'
                    DomRepresentation representation;
                    try {
                        representation = new DomRepresentation(MediaType.TEXT_XML);
                        Document d = representation.getDocument();
                        Element jobIDElement = d.createElement("status");
                        // String progress =
                        // DownloadFile.getNumberProcessed().get(jobID);
                        jobIDElement.appendChild(d.createTextNode("Still processing"));
                        d.appendChild(jobIDElement);
                        d.normalizeDocument();
                        getResponse().setEntity(representation);
                        getResponse().setStatus(Status.SUCCESS_OK);
                        return representation;
                    } catch (IOException e) {
                        logger.warn("Problem returning status for job " + jobID);
                        getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
                    }
                }
            }

        }

        return null;

    }

    public void setConfig(Configuration config) {
        this.config = config;
    }

    public Configuration getConfig() {
        return config;
    }
}
